package com.eva.framework.dict.utils;

import com.eva.framework.cache.CacheProxy;
import com.eva.framework.common.constants.CacheKeys;
import com.eva.framework.common.constants.ResponseStatus;
import com.eva.framework.common.exception.BusinessException;
import com.eva.framework.common.utils.Utils;
import com.eva.framework.dict.model.SystemDictCache;
import com.eva.framework.dict.model.SystemDictDataCache;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Map;

/**
 * 系统字典帮助类
 * 用于方便获取字典数据
 */
@Component
public final class SystemDictHelper {

    private CacheProxy<String, Map<String, SystemDictCache>> cacheProxy;

    private String appId;

    private SystemDictHelper() {}

    public static SystemDictHelper build (String appId) {
        SystemDictHelper helper = new SystemDictHelper();
        helper.appId = appId;
        helper.cacheProxy = Utils.SpringContext.getBean(CacheProxy.class);
        return helper;
    }

    /**
     * 获取字典
     *
     * @param code 字典编码
     * @return DictCache
     */
    public SystemDictCache getDict (String code) {
        return getMap().get(code);
    }

    /**
     * 获取字典数据
     *
     * @param code 字典编码
     * @param dataValue 数据值
     * @return DictDataCache
     */
    public SystemDictDataCache getDictData (String code, String dataValue) {
        SystemDictCache dictCache = this.getDict(code);
        for (SystemDictDataCache dictDataCache : dictCache.getDataList()) {
            if (dictDataCache.getValue().equals(dataValue)) {
                return dictDataCache;
            }
        }
        throw new RuntimeException("找不到字典数据，字典编码：" + code + "，数据值：" + dataValue);
    }

    /**
     * 获取字典数据标签
     *
     * @param code 字典编码
     * @param dataValue 数据值
     * @return 字典数据标签
     */
    public String getDictDataLabel (String code, String dataValue) {
        return this.getDictData(code, dataValue).getLabel();
    }

    /**
     * 断言数据，如果在指定字典中不存在数据，则抛出异常
     *
     * @param code 字典编码
     * @param dataValue 字典数据值
     * @param message 错误消息
     */
    public void assertData (String code, String dataValue, String message) {
        this.assertData(code, dataValue, ResponseStatus.BAD_REQUEST, message);
    }

    /**
     * 断言数据，如果在指定字典中不存在数据，则抛出异常
     *
     * @param code 字典编码
     * @param dataValue 字典数据值
     * @param status 响应状态
     * @param message 错误消息
     */
    public void assertData (String code, String dataValue, ResponseStatus status, String message) {
        SystemDictCache dictCache = this.getDict(code);
        if (dictCache == null) {
            throw new BusinessException(status, message);
        }
        for (SystemDictDataCache dictDataCache : dictCache.getDataList()) {
            if (dictDataCache.getValue().equals(dataValue)) {
                return;
            }
        }
        throw new BusinessException(status, message);
    }

    /**
     * 读取字典缓存数据
     *
     * @return 缓存数据
     */
    public Collection<SystemDictCache> getList() {
        return cacheProxy.get(this.getCacheKey()).values();
    }

    /**
     * 读取字典缓存数据
     *
     * @return 缓存数据
     */
    public Map<String, SystemDictCache> getMap() {
        return cacheProxy.get(this.getCacheKey());
    }

    /**
     * 获取缓存键，格式：{应用ID}_{CacheKeys.DICTIONARIES}
     * @return String
     */
    public String getCacheKey () {
        return this.appId + "_" + CacheKeys.DICTIONARIES;
    }
}
